//a=new Array() === a=[]; a=new Array(5) === a=[5]; a=new Object() === a={};
//but Array and Object can be extended, so if you wan creat a object not been extended, using {}, or [];
//also Array can used as an object.
//var HashMap = new Function("key","value","this.entries={};this.entries[key]=value;");
//var HashMap= function(key,value){

//if need use HashMap.remove(), then need import Array.js;

HashMap=function(){this.initialize.apply(this, arguments);}
HashMap.prototype={
	initialize:
	function(){
		this.length=0;
		this.arrays=[];
		this.entries={};
	},
	
	Entry:
	function(key,value){
		if(typeof(key)=="undefined"||key==null)return;
		this.key=key;
		this.value=value;
	},
	
	size:
	function(){
		return this.length;
	},
	
	clear:
	function(){
		this.initialize();
		//TODO:shouldn't replace the object, should remove all elements;
	},

	clone:
	function(){
		var oThis = this;
		var newMap = new HashMap();
		newMap.putAll(oThis);
		return newMap;
	},
	
	remove:
	function(key){
		if(typeof(key)=="undefined"||key==null)return;
		var theEntry = this.entries;
		if( theEntry[key] ){
			arrayRemoveObj(this.arrays,theEntry[key])
			this.length=this.arrays.length
			theEntry[key]=undefined;
			try{//real delete from object;
				//not the standard from ECMAScript;
				delete theEntry[key];
			}catch(e){}
		}
	},
	
	put:
	function(key,value){
		if(typeof(key)=="undefined"||key==null)return;
		var theEntry = this.entries;
		if( theEntry[key] ){
			theEntry[key].value=value;
		}else{
			var theArray =this.arrays;
			
			//theEntry[key]=theArray[theArray.length]=new this.Entry(key,value);
			var newEntry = new this.Entry(key,value);
			theEntry[key]=newEntry;
			theArray.push(newEntry);
			
			this.length	 = theArray.length;
		}	
	},
	
	putAll:
	function(srcMap){
		var entries = srcMap.entrySet();
		//this.arrays.concat(srcMap.arrays);
		//but need to sync this.entries...
		for(var i in entries){
			this.put(entries[i].key,entries[i].value);
		}
		//this.length = theArray.length;//included in put method.
	},
	
	load:
	function(src){
		if (typeof(str)=='string' && src.length>0){
			if(src.substr(0,1)=='{'){
				this.load(eval('('+src+')'));
			}else{
				this.load(eval('({'+src+'})'));
				/*
				var arrs=src.split(',');
				for(var arr in arrs){
					var attr = arr.split(':');
					if(attr.length==2){
						this.put(attr[0],attr[1]);
					}
				}
				*/
			}
		}else if(typeof(src)=='object'){
			for(var k in src){
				this.put(k, src[k]);
			}
		}
	},
		
	get: 
	function(key){
		return this.getValue(key);
	},
	
	item: 
	function(n){
		return this.arrays[n];
	},
	
	getValue: 
	function(key){
		if(this.entries[key]){
			return this.entries[key].value;
		}else{
			return null;
		}
	},
		
	getEntry: 
	function(key){
		if(this.entries[key]){
			return this.entries[key];
		}else{
			return null;
		}
	},
			
	entrySet: 
	function(){
		return this.arrays;
	},
	
	keySet: 
	function(){
		var arr = [];
		var theArray=this.arrays;
		for(var i in theArray){
			arr[i] = theArray[i].key;
		}
		return arr;
	},
	
	values: 
	function(){
		var arr = [];
		var theArray=this.arrays;
		for(var i in theArray){
			arr[i] = theArray[i].value;
		}
		return arr;	
	},
	
	reverse:
	function(){
		var oldArray = this.arrays;
		var theLength = this.length;
		this.arrays=[];//new Array;
		for(var i=oldArray.length;i>0;i--){
			this.arrays[theLength-i]=oldArray[i-1];
		}
		return this;
	},
	
	toArray:function(){
		var arr = [];
		var theArray=this.arrays;
		for(var i in theArray){
			arr[theArray[i].key] = theArray[i].value;
		}
		return arr;	
	},
	
	toUrlParams: 
	function(/*Boolean*/ getAll, prefix){
		var namePrefix = prefix?prefix:"";
		var theArray = this.arrays;
		var str="";
		for(var i=0;i<theArray.length;i++){
			if( typeof(theArray[i].value)=="undefined"||
				typeof(theArray[i].value)=="object" ){
				continue;
			}
			str += ("&" + namePrefix + theArray[i].key + "=" + escape(theArray[i].value) );
		}
		return getAll ? str : str.substring(1,str.length);
	},
	
	toString: 
	function(){
		var theArray = this.arrays;
		var str="";
		for(var i=0;i<theArray.length;i++){
			if(i==0){ str += (theArray[i].key+":"+theArray[i].value); }
			else{str += (", "+theArray[i].key+":"+theArray[i].value);}
		}
		return str;
	},
	
	toKeyString: 
	function(){
		var theArray = this.arrays;
		var str="";
		for(var i=0;i<theArray.length;i++){
			if(i==0){ str += theArray[i].key; }
			else{ str += (","+theArray[i].key); }
		}
		return str;
	},
	
	toValueString: 
	function(){
		var theArray = this.arrays;
		var str="";
		for(var i=0;i<theArray.length;i++){
			if(i==0){ str += theArray[i].value; }
			else{ str += (","+theArray[i].value); }
		}
		return str;
	}
}
